﻿using furion.blog.Domain.IRepositories;
using furion.blog.Domain.MySQL;
using furion.blog.Domain.Query;
using furion.blog.Domain.Shared;
using Furion.FriendlyException;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace furion.blog.EntityFramework.Core.Repositories
{
    public class BaseRepository<T> : BaseSqlSugarRepository<T> , IBaseRepository<T> where T : BaseModel , new()
    {

        public readonly ISqlSugarClient _db;
        public BaseRepository(ISqlSugarClient db)
        {
            this._db = db;
        }


        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> SaveModel(T model) {
            return await base.InsertAsync(model);
        }

        public async Task<bool> SaveModels(List<T> datas) {
            return await base.InsertRangeAsync(datas);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> UpdateModel(T model) {
            return await base.UpdateAsync(model);
        }

        public async Task<bool> UpdateModels(List<T> models)
        {
            return await base.UpdateRangeAsync(models);
        }

        /// <summary>
        /// 通过id 获取
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<T> Get(long id) {
            return (T)await base.GetByIdAsync(id);
        }

        /// <summary>
        /// 查找第一个
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<T> First(BaseDetailQuery<T> query) {
            //return await base.GetFirstAsync(query.Exp());
            try
            {
                var (e, o) = query.OrderBy();
                return await this._db.Queryable<T>()
                    .IgnoreColumns(query.IgnoreColumns())
                    .Where(query.Exp())
                    .OrderBy(e, o)
                    .FirstAsync();
            }
            catch (Exception ex)
            {
                throw Oops.Oh(ex.Message);
            }
        }

        /// <summary>
        /// 返回头几条数据
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<List<T>> Top(BaseDetailQuery<T> query)
        {
            try
            {
                var (e, o) = query.OrderBy();
                return await this._db.Queryable<T>()
                    .IgnoreColumns(query.IgnoreColumns())
                    .Where(query.Exp())
                    .OrderBy(e, o)
                    .Take(query.Top)
                    .ToListAsync();
            }
            catch (Exception ex)
            {
                throw Oops.Oh(ex.Message);
            }
        }

        /// <summary>
        /// 查询所有
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<List<T>> All(BaseDetailQuery<T> query) {
            try
            {
                var (e, o) = query.OrderBy();
                return await this._db.Queryable<T>().IgnoreColumns(query.IgnoreColumns()).Where(query.Exp()).OrderBy(e, o).ToListAsync();
            }
            catch (Exception ex) {
                throw Oops.Oh(ex.Message);
            }
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public async Task<PageVO> List(BasePageQuery query)
        {
            try
            {
                var (strWhere, sqlParams) = query.QueryParams();
                long startIndex = query.GetStartIndex();

                string countSql = query.GetCountSQL();
                string dataSql = query.GetDataSQL();

                long total = await this._db.Ado.GetLongAsync(countSql, sqlParams);
                var data = await this._db.Ado.GetDataTableAsync(dataSql, sqlParams);
                return new PageVO { Total = total, Records = data };
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return new PageVO { Total = 0L, Records = null };
        }

        
    }
}
